package server

import (
	"github.com/gin-contrib/requestid"
	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"

	"mychat/api"
	"mychat/docs"
	"mychat/internal/common/constants"
	"mychat/internal/common/errors"
	"mychat/internal/common/logger"
	"mychat/internal/server/middleware"
	"mychat/internal/service/helloworld"
)

func (s *Server) initRouter() *gin.Engine {
	lg := s.lg.WithCustomTag(logger.LoggerTagMiddleware)

	router := gin.New()
	router.Use(middleware.Cors())
	router.Use(requestid.New(
		requestid.WithCustomHeaderStrKey(constants.HeaderRequestId),
	))

	router.Use(middleware.Recovery(lg, &errors.DefaultError),
		middleware.LoggerHandler(lg))

	docs.SwaggerInfo.BasePath = "/"
	router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
	//
	router.GET("/ping", GenHandler(lg, nil, s.svc.HelloWorld.Ping))
	router.GET("/hi/:name", GenHandler(lg, "name", s.svc.HelloWorld.Hi))
	router.GET("/hello", GenHandler(lg, &helloworld.HelloRequest{}, s.svc.HelloWorld.Hello))

	v1group := router.Group("/v1")
	{
		userService := s.svc.UserService
		usergroup := v1group.Group("/user/")
		{
			usergroup.POST("/register", GenHandler(lg, &api.CreateUserRequest{}, userService.CreateUser))
			usergroup.POST("/login", GenHandler(lg, &api.UserLoginRequest{}, userService.Login))
			usergroup.Use(middleware.JwtAuth(s.bs.Server.Http, lg))
			{
				usergroup.PUT("/user/logout", GenHandler(lg, nil, userService.Logout))
			}
		}

		v1group.Use(middleware.JwtAuth(s.bs.Server.Http, lg))
		{

			friendgroup := v1group.Group("/friend")
			{
				friendgroup.POST("/apply", GenHandler(lg, &api.ApplyFriendRequest{}, userService.ApplyFriend))
				friendgroup.POST("/confirm", GenHandler(lg, &api.ConfirmFriendRequest{}, userService.ConfirmFriend))
				friendgroup.DELETE("/remove", GenHandler(lg, &api.DeleteFriendRequest{}, userService.DeleteFriend))
			}

			chatgroup := v1group.Group("/mgchat/")
			chatService := s.svc.ChatService
			{
				chatgroup.POST("/chat", GenHandler(lg, &api.NewChatRequest{}, chatService.NewChat))
				chatgroup.GET("/chat/:chatid", GenHandler(lg, "chatid", chatService.GetChat))
				chatgroup.GET("/chats", GenHandler(lg, &api.ListChatRequest{}, chatService.ListChats))
				chatgroup.DELETE("/chat", GenHandler(lg, &api.DeleteChatRequest{}, chatService.DeleteChat))
				chatgroup.PUT("/chat/invite", GenHandler(lg, &api.InviteFreindRequest{}, chatService.ChatInviteFriend))
				chatgroup.PUT("/chat/remove", GenHandler(lg, &api.RemoveFreindRequest{}, chatService.ChatRemoveFriend))
				chatgroup.PATCH("/chat", GenHandler(lg, &api.ChangeChatNameRequest{}, chatService.ChangeChatName))
			}

			v1group.GET("/ws", s.svc.ChatHub.ServeWs())
		}
	}

	return router
}
